﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using UnityEditor.Experimental.GraphView;
using UnityEngine.UIElements;

namespace SkillEditor
{
    public class SkillEditorGraph : GraphView
    {

        public SkillEditorSpaceWindow editorWindow;

        public SkillEditorGraph(SkillEditorSpaceWindow editorWindow, SkillEditorSearchWindowProvider searchWindowProvider) : base()
        {
            this.editorWindow = editorWindow;

            SetupZoom(ContentZoomer.DefaultMinScale, ContentZoomer.DefaultMaxScale);
            Insert(0, new GridBackground());

            //this.SetupZoom(0.05f, 8);
            this.AddManipulator(new ContentDragger());
            this.AddManipulator(new SelectionDragger());
            this.AddManipulator(new RectangleSelector());
            this.AddManipulator(new ClickSelector());

            //this.styleSheets.Add(Resources.Load<StyleSheet>("GraphView"));
            style.flexGrow = 1;

            nodeCreationRequest += context =>
            {
                SearchWindow.Open(new SearchWindowContext(context.screenMousePosition), searchWindowProvider);
            };

            canPasteSerializedData = PasteSerialized;
            unserializeAndPaste = UnserializeAndPaste;
            serializeGraphElements = SerializeGraphElementsHandler;
        }

        private string SerializeGraphElementsHandler(IEnumerable<GraphElement> elements)
        {
            UnityEngine.Debug.Log("SerializeGraphElementsHandler");

            List<SkillNode> list = new List<SkillNode>();
            foreach (GraphElement item in elements)
            {
                SkillEditorGraphNode node = item as SkillEditorGraphNode;
                if (node == null)
                {
                    continue;
                }

                list.Add(node.GetCopyData());
            }

            JsonSerializerSettings settings = new JsonSerializerSettings()
            {
                Formatting = Formatting.Indented,
                NullValueHandling = NullValueHandling.Ignore,
                DefaultValueHandling = DefaultValueHandling.Ignore
            };

            return JsonConvert.SerializeObject(list, settings);
        }

        private void UnserializeAndPaste(string operationName, string data)
        {
            if (operationName != "Paste")
                return;

            List<SkillNode> list = JsonConvert.DeserializeObject<List<SkillNode>>(data);
            for (int i = 0; i < list.Count; i++)
            {
                list[i].id = SkillEditorSpaceWindow.GuidTo16String();
                editorWindow.AddNode(list[i]);
            }
        }

        private bool PasteSerialized(string data)
        {
            UnityEngine.Debug.Log("PasteSerialized");
            UnityEngine.Debug.Log(data);

            return false;
        }

        public override List<Port> GetCompatiblePorts(Port startAnchor, NodeAdapter nodeAdapter)
        {
            var compatiblePorts = new List<Port>();
            foreach (var port in ports.ToList())
            {
                if (startAnchor.node == port.node ||
                    startAnchor.direction == port.direction ||
                    startAnchor.portType != port.portType)
                {
                    continue;
                }

                compatiblePorts.Add(port);
            }
            return compatiblePorts;
        }

        protected override void CollectCopyableGraphElements(IEnumerable<GraphElement> elements, HashSet<GraphElement> elementsToCopySet)
        {
            base.CollectCopyableGraphElements(elements, elementsToCopySet);
        }

        protected override bool canPaste => true;
    }
}